package airacrobats.io.data;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;

/**
 * The sound data.
 */
public class SoundData
{
    /**
     * Path to the file.
     */
    private String filePath;
    /**
     * Audio format.
     */
    private AudioFormat decodedFormat;
    /**
     * Sound bytes.
     */
    private List<byte[]> bytes;

    /**
     * @param filePath The file path.
     */
    public SoundData(String filePath)
    {
        this.filePath = filePath;
        bytes = new ArrayList<byte[]>();
    }

    /**
     * Reads the bytes from the audio file.
     * @throws UnsupportedAudioFileException Thrown if the file format is not supported.
     * @throws IOException Thrown if an I/O error occurs.
     */
    public void read() throws UnsupportedAudioFileException, IOException
    {
        File file = new File(filePath);

        AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(file);
        AudioInputStream decAudioInputStream = null;

        if (audioInputStream != null)
        {
            AudioFormat baseFormat = audioInputStream.getFormat();
            decodedFormat = new AudioFormat(
                    AudioFormat.Encoding.PCM_SIGNED,
                    baseFormat.getSampleRate(),
                    16,
                    baseFormat.getChannels(),
                    baseFormat.getChannels() * 2,
                    baseFormat.getSampleRate(),
                    false);
            
            decAudioInputStream = AudioSystem.getAudioInputStream(decodedFormat, audioInputStream);

            byte[] data = new byte[4096];
            int nBytesRead = 0;
            while (nBytesRead != -1)
            {
                nBytesRead = decAudioInputStream.read(data, 0, data.length);
                if (nBytesRead > 0)
                {
                    byte[] b = new byte[nBytesRead];
                    System.arraycopy(data, 0, b, 0, nBytesRead);
                    bytes.add(b);
                }
            }

            decAudioInputStream.close();
            audioInputStream.close();
        }
    }

    /**
     * @return The audio format.
     */
    public AudioFormat getDecodedFormat()
    {
        return decodedFormat;
    }

    /**
     * @return The audio bytes.
     */
    public List<byte[]> getBytes()
    {
        return bytes;
    }
}
